
/*========================================================================================
 *                                                                                      *
 *               Copyright(c) 2013-2014, Cha SangWoo, All rights reserved.              *
 *                                                                                      *
 * This file is part of ChaOS.                                                          *
 *                                                                                      *
 * Permission to use, copy, modify, and distribute this software in source and binary   *
 * forms and its documentation for any purpose and without fee is hereby granted,       *
 * provided that the above copyright notice appear in all copies and that both that     *
 * copyright notice and this permission notice appear in supporting documentation.      *
 *                                                                                      *
 * THIS SOFTWARE IS PROVIDED BY THE CHA SANGWOO AND CONTRIBUTORS "AS IS" AND ANY        *
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED            *
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.   *
 * IN NO EVENT SHALL CHA SANGWOO OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,    *
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT         *
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,          *
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF            *
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE      *
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,                    *
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                                   *
 *                                                                                      *
========================================================================================*/

#include "co_core.h"
#include "co_heap.h"

#ifdef __cplusplus
    extern "C" {
    namespace ChaOS {
#endif

//////////////////////////////////////  < BEGIN >  ///////////////////////////////////////


/*======================================================================================*/
/*!
    @fn             VOID* co_heap_alloc(UINT byte)

    @brief          Allocate memory blocks.

    @param [in]     size - Bytes to allocate.

    @return         a void pointer to the allocated space.
                    NULL, if there is insufficient memory available.

    - HISTORY -
    [V00.00.01] 2014-03-23 [aireat] - Created.
*/
/*======================================================================================*/
VOID* co_heap_alloc(UINT size)
{
    VOID      *pmemblock;

    // check validation
    CO_ASSERT(_gst_heap_info.pcur != NULL);
    CO_ASSERT(_gst_heap_info.pmax != NULL);
    CO_ASSERT(_gst_heap_info.pmax >= _gst_heap_info.pcur);
    CO_ASSERT(size > 0);

    pmemblock = NULL;

#if (FLAG_USE_HEAP_ALIGN == CO_ENABLE)
    size  = (UINT)SIZE_ALIGN(size, sizeof(UINT));
#endif

    // check remain size
    if ((UINT)(_gst_heap_info.pmax - _gst_heap_info.pcur) >= size)
    {
        pmemblock = (VOID*)_gst_heap_info.pcur;
        _gst_heap_info.pcur += size;
    }

    CO_ASSERT_MSG(pmemblock, "[heap] not enought heap\n");

    // Trace of usage
#if (FLAG_USE_HEAP_TRACE == CO_ENABLE)
    {
        UINT       remain_size;

        remain_size = (UINT)(_gst_heap_info.pmax - _gst_heap_info.pcur);

        if (remain_size < 1024)
        {
            _port_log_printf("HEAP", "request(%7d) - remain(%10d)\n", 
                             size, remain_size);
        }
        else
        if (remain_size < (1024*1024))
        {
            _port_log_printf("HEAP", "request(%7d) - remain(%10d) %d KB\n", 
                             size, remain_size, (remain_size/(1024)));
        }
        else
        {
            _port_log_printf("HEAP", "request(%7d) - remain(%10d) %d MB\n", 
                             size, remain_size, (remain_size/(1024*1024)));
        }
    }
#endif

    return pmemblock;
}

/*======================================================================================*/
/*!
    @fn             VOID co_heap_free(VOID *pmemblock)

    @brief          Deallocates or frees a address.

    @param [in]     pmemblock - Previously allocated memory block to be freed.

    @return         None

    - HISTORY -
    [V00.00.01] 2014-03-23 [aireat] - Created.
*/
/*======================================================================================*/
VOID co_heap_free(VOID *pmemblock)
{
    // check validation
    CO_ASSERT_MSG(0, "[heap] not support\n");

    // not support
}

//////////////////////////////////////  <  END  >  ///////////////////////////////////////

#ifdef __cplusplus
    } /* namespace ChaOS */
    } /* extern "C" */
#endif

